package gui;
import gameengine.EntityMgr;
import gameengine.GameMgr;
import gameengine.HiScoreMgr;
import gameobjects.Entity;
import gameobjects.PlayerEntity;
import inputmanager.InputMgr;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class Screen extends JFrame {
	
	private static final long serialVersionUID = 1392043371649847041L;
	public static final int WIDTH = 720;
	public static final int HEIGHT = 405;
	public static final String TITLE = "The Vigilante";
	public static final int SCALE = 5;
	private final int		FLICKER = 500;
	private final int		MENU_X = 255;
	private final int		MENU_Y = 155;
	private final int		MENU_GAP = 30;
	private final Font		FONT_MENU = new Font(Font.MONOSPACED,Font.BOLD,18);
	private final Font		FONT_SCORE = new Font(Font.MONOSPACED,Font.BOLD,20);
	public static BufferStrategy buffer;
	private GameMgr			gameMgr;
	private EntityMgr		entityMgr;
	private Entity			camera;
	private Graphics		graphics;
	private HiScoreMgr		hiScoreMgr;
	
	public Screen(GameMgr g, EntityMgr e, Entity c, InputMgr i, HiScoreMgr h)
	{
		gameMgr = g;
		entityMgr = e;
		camera = c;
		hiScoreMgr = h;
		setTitle(TITLE);
		setResizable(false);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setIgnoreRepaint(true);
		Canvas canvas = new Canvas();
		canvas.setIgnoreRepaint( true );
		canvas.setSize( WIDTH, HEIGHT );
		add(canvas);
		pack();
		setVisible(true);
		canvas.createBufferStrategy( 2 );
		buffer = canvas.getBufferStrategy();
		setLocationRelativeTo(null);
        this.addKeyListener(i);
        canvas.addKeyListener(i);
	}
	
	public void renderTick(long tick){
		try {
			
		    graphics = buffer.getDrawGraphics(); 
		    
		    graphics.setColor(new Color(0x180707));
		    graphics.fillRect(0, 0, Screen.WIDTH, Screen.HEIGHT);
		    
		    int gameState = gameMgr.getGameState();
		    if (gameState == GameMgr.STATE_PREMENU){
		    	renderPreMenu(tick);
		    }
		    else if (gameState == GameMgr.STATE_MENU){
		    	renderMenu(tick);
		    }
		    else if (gameState == GameMgr.STATE_LIVES){
		    	renderLives(tick);
		    }
		    else if (gameState == GameMgr.STATE_HELP){
		    	renderHelp(tick);
		    }
		    else if (gameState == GameMgr.STATE_LOAD){
		    	renderLoad(tick);
		    }
		    else if (gameState == GameMgr.STATE_HISCORE){
		    	renderHiScore(tick);
		    }
		    else if (gameState == GameMgr.STATE_SCORE_ENTER){
		    	renderScore(tick);
		    }
		    else if (gameState == GameMgr.STATE_CREDITS){
		    	renderCredits(tick);
		    }
		    else if (gameState == GameMgr.STATE_GAME || gameState == GameMgr.STATE_PAUSE){
		    	renderGame(tick);
	    		if (gameState == GameMgr.STATE_PAUSE){
	    			renderPause(tick);
	    		}
		    }
		    else if (gameState == GameMgr.STATE_GAME_LOSE)
		    {
		    	renderLose(tick);
		    }
		    else if (gameState == GameMgr.STATE_GAME_WIN)
		    {
		    	renderWin(tick);
		    }
		    
		    if( !buffer.contentsLost() )
		    	buffer.show();
		    
		    Thread.yield();

		} finally {
			if( graphics != null ) 
		    	graphics.dispose();
		}
	}
	
	public void renderPause(long tick){
		graphics.setColor(new Color(0f, 0f, 0f, .8f));
	    graphics.fillRect(0, 0, Screen.WIDTH, Screen.HEIGHT);
	    graphics.setColor(Color.WHITE);
	    graphics.setFont(FONT_MENU);
		graphics.drawString("PAUSED", MENU_X, MENU_Y);
    	graphics.drawString("Resume Game", MENU_X, MENU_Y + MENU_GAP);
		graphics.drawString("Exit Game", MENU_X, MENU_Y + 2 * MENU_GAP);
	    graphics.fillPolygon(new int[]{MENU_X - 20, MENU_X - 20, MENU_X - 10}, new int[]{MENU_Y + (gameMgr.getMenuSelect() + 1) * MENU_GAP,MENU_Y + (gameMgr.getMenuSelect() + 1) * MENU_GAP - FONT_MENU.getSize(), MENU_Y + (gameMgr.getMenuSelect() + 1) * MENU_GAP - FONT_MENU.getSize()/2}, 3);
	}
	
	public void renderGame(long tick){
		PlayerEntity pc = entityMgr.getPlayerEntity();
		try {
			BufferedImage bg = ImageIO.read(getClass().getResource("..\\stages/" + gameMgr.getStage() + "/background.png"));
			graphics.drawImage(bg, -camera.getX(), 0, bg.getWidth()*SCALE, bg.getHeight()*SCALE, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
    	for (int i = 0; i < entityMgr.getEntityList().size(); i++) {
			entityMgr.getEntityList().get(i).draw(graphics, camera);
		}
	    graphics.setColor(Color.WHITE);
	    graphics.setFont(FONT_SCORE);
		graphics.drawString(String.format("Score: %08d", gameMgr.getScore()), 525, 30);
		graphics.drawString("Stage: " + gameMgr.getStage(), 17, 30);
		if (pc.getWeaponName() == "handgun")
			graphics.drawString("- / -",625,390);
		else
			graphics.drawString(pc.getBulletCount() + " / " + pc.getMaxBullet(),625,390);
		try {
			BufferedImage w = ImageIO.read(getClass().getResource("..\\sprites/" + pc.getWeaponName() +".png"));
			graphics.drawImage(w, 595, 373, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void renderLives(long tick){
	    graphics.setColor(Color.WHITE);
	    graphics.setFont(FONT_SCORE);
		graphics.drawString("Lives: " + gameMgr.getLives(), 300, 300);
		graphics.drawString(String.format("Score: %08d", gameMgr.getScore()), 525, 30);
		graphics.drawString("Stage: " + gameMgr.getStage(), 17, 30);
	}
	
	public void renderHelp(long tick){
		graphics.setColor(Color.WHITE);
		graphics.setFont(FONT_MENU);
		graphics.drawString("HELP", 30, 50);
		graphics.drawString("CONTROLS", 60, 100);
		graphics.drawString("W: Jump", 100, 135);
		graphics.drawString("A: Move to left", 100, 155);
		graphics.drawString("D: Move to right", 100, 175);
		graphics.drawString("S: Drop down", 100, 195);
		graphics.drawString("O: Fire weapon", 100, 215);
		graphics.drawString("ESC: Pause game", 100, 235);
		graphics.drawString("WEAPONS", 310, 100);
		graphics.drawString(" - Handgun", 372, 145);
		graphics.drawString(" - Shotgun", 372, 165);
		graphics.drawString(" - Light Machine Gun", 372, 185);
		graphics.drawString(" - Rocket Launcher", 372, 205);
		graphics.drawString(" - Chaser", 372, 225);
		try {
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\sprites/handgun.png")), 350, 130, null);
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\sprites/shotgun.png")), 350, 150, null);
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\sprites/lmg.png")), 350, 170, null);
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\sprites/rocket.png")), 350, 190, null);
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\sprites/chaser.png")), 350, 210, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
		graphics.drawString("Back", 50, 350);
		graphics.fillPolygon(new int[]{30,30,40},new int[]{350,350 -  FONT_MENU.getSize(),350 -  FONT_MENU.getSize()/2},3);
	}
	
	public void renderCredits(long tick){
		graphics.setColor(Color.WHITE);
		graphics.setFont(FONT_MENU);
		graphics.drawString("CREDITS", 310, 50);
		graphics.drawString("Berkay Cakir", 290, 150);
		graphics.drawString("Ulas Sert", 300, 180);
		graphics.drawString("Ahad Suleymanli", 265, 210);
		graphics.drawString("Ipek Susoy", 295, 240);
		graphics.drawString("Back", 50, 350);
		graphics.fillPolygon(new int[]{30,30,40},new int[]{350,350 -  FONT_MENU.getSize(),350 -  FONT_MENU.getSize()/2},3);
	}
	
	public void renderLose(long tick)
	{
		graphics.setColor(Color.WHITE);
		graphics.setFont(FONT_SCORE);
		graphics.drawString("GAME OVER", 300, 200);
	}
	
	public void renderWin(long tick)
	{
		graphics.setColor(Color.WHITE);
		graphics.setFont(FONT_SCORE);
		graphics.drawString("YOU WIN", 300, 200);
	}
	
	public void renderMenu(long tick){
		try {
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\MENUSCREEN.png")), 0, 0, null);
			
		    graphics.setColor(Color.WHITE);
		    graphics.setFont(FONT_MENU);
    		graphics.drawString("Load Stage", MENU_X, MENU_Y + MENU_GAP);
    		graphics.drawString("Difficulty: " + gameMgr.getDifficultyString(), MENU_X, MENU_Y + 2 * MENU_GAP);
    		graphics.drawString("High Scores", MENU_X, MENU_Y + 3 * MENU_GAP);
    		graphics.drawString("Help", MENU_X, MENU_Y + 4 * MENU_GAP);
    		graphics.drawString("Credits", MENU_X, MENU_Y + 5 * MENU_GAP);
    		graphics.drawString("Exit", MENU_X, MENU_Y + 6 * MENU_GAP);
		    if (null == gameMgr.getTime("startTime") || tick % FLICKER < FLICKER/2){
		    	graphics.drawString("Play Game", MENU_X, MENU_Y);
		    	graphics.fillPolygon(new int[]{MENU_X - 20, MENU_X - 20, MENU_X - 10}, new int[]{MENU_Y + gameMgr.getMenuSelect() * MENU_GAP,MENU_Y + gameMgr.getMenuSelect() * MENU_GAP - FONT_MENU.getSize(), MENU_Y + gameMgr.getMenuSelect() * MENU_GAP - FONT_MENU.getSize()/2}, 3);
		    }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void renderLoad(long tick){
	    graphics.setColor(Color.WHITE);
	    graphics.setFont(FONT_MENU);
		graphics.drawString("Load Stage", MENU_X - MENU_GAP * 3, MENU_Y - 2 * MENU_GAP);
    	graphics.drawString("Stage 2", MENU_X, MENU_Y);
		graphics.drawString("Stage 3", MENU_X, MENU_Y + MENU_GAP);
		graphics.drawString("Stage 4", MENU_X, MENU_Y + 2 * MENU_GAP);
		graphics.drawString("Back", MENU_X, MENU_Y + 3 * MENU_GAP);
	    graphics.fillPolygon(new int[]{MENU_X - 20, MENU_X - 20, MENU_X - 10}, new int[]{MENU_Y + gameMgr.getMenuSelect() * MENU_GAP,MENU_Y + gameMgr.getMenuSelect() * MENU_GAP - FONT_MENU.getSize(), MENU_Y + gameMgr.getMenuSelect() * MENU_GAP - FONT_MENU.getSize()/2}, 3);
	}
	
	public void renderPreMenu(long tick){
		try {
			graphics.drawImage(ImageIO.read(getClass().getResource("..\\MENUSCREEN.png")), camera.getX(), 0, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void renderHiScore(long tick){
		graphics.setColor(Color.WHITE);
		graphics.setFont(FONT_MENU);
		graphics.drawString("HIGH SCORES", 60, 50);
		graphics.drawString("NAME                            SCORE", 60, 95);
		int[] scores = hiScoreMgr.getScores();
		String[] names = hiScoreMgr.getNames();
		for (int i = 0; i < scores.length; i++) {
			graphics.drawString(names[i] + "                            " + String.format("%08d", scores[i]), 100, 115 + 20*i);
		}
		/*graphics.drawString("W: Jump", 100, 135);
		graphics.drawString("A: Move to left", 100, 155);
		graphics.drawString("D: Move to right", 100, 175);
		graphics.drawString("S: Drop down", 100, 195);
		graphics.drawString("O: Fire weapon", 100, 215);
		graphics.drawString("WEAPONS", 310, 100);
		graphics.drawString(" - Handgun", 372, 135);
		graphics.drawString(" - Shotgun", 372, 155);
		graphics.drawString(" - Light Machine Gun", 372, 175);
		graphics.drawString(" - Rocket Launcher", 372, 195);
		graphics.drawString(" - Chaser", 372, 215);*/
		graphics.drawString("Back", 50, 350);
		graphics.fillPolygon(new int[]{30,30,40},new int[]{350,350 -  FONT_MENU.getSize(),350 -  FONT_MENU.getSize()/2},3);
	}
	
	public void renderScore(long tick){
	    graphics.setColor(Color.WHITE);
	    graphics.setFont(FONT_MENU);
		graphics.drawString("HIGH SCORE", MENU_X - MENU_GAP * 3, MENU_Y - 2 * MENU_GAP);
		graphics.drawString("SCORE: " + gameMgr.getScore(), MENU_X, MENU_Y - MENU_GAP);
    	graphics.drawString("NAME: " + gameMgr.getName(), MENU_X, MENU_Y);
	    graphics.fillPolygon(new int[]{MENU_X + 11 * (gameMgr.getMenuSelect() + 6), MENU_X + 5 + 11 * (gameMgr.getMenuSelect() + 6), MENU_X + 10 + 11 * (gameMgr.getMenuSelect() + 6)}, new int[]{MENU_Y + 15, MENU_Y + 5, MENU_Y + 15 }, 3);
	}
}
